#include <Windows.h>
#include <gl/gl.h>
#include "global.h"
#include "NDVector.hpp"
#include "RoundMenu.h"
#include "RoundMenuItem.h"
#include "SphericalRectangularTransform.h"

#define MENU_DEST_CENTER_ANGLE_RAD 0.2f
#define MENU_STEP 10.0f
#define INNER_RATE 0.5f

using namespace std;

RoundMenu::RoundMenu () : BaseMenu (L"Comic Sans MS", 24.0f, 1.002f),
  _curCenterAngleRad (0.0f) {}


void RoundMenu::draw () const
{
  glTextDrawer::getSingleton ().setFont (__font);
  if (status != HIDE)
  {
    glPushMatrix ();
    glRotatef (R2D (__longitude), 0.0f, 1.0f, 0.0f);
    glRotatef (90.0f - R2D (__latitude), 1.0f, 0.0f, 0.0f);
    glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
    for (size_t i = 0; i < __items.size (); ++i)
    {
      ((RoundMenuItem*)(BaseMenuItem*)__items[i])->
        draw (__globeRadius, _curCenterAngleRad);
      glRotatef (360.0f / (float) __items.size (), 0.0f, 1.0f, 0.0f);
    }
    glPopMatrix ();
  }
}


void RoundMenu::doAnimation ()
{
  if (status == HIDE_TO_SHOW)
  {
    _curCenterAngleRad += MENU_DEST_CENTER_ANGLE_RAD / MENU_STEP;
    if (_curCenterAngleRad >= MENU_DEST_CENTER_ANGLE_RAD)
    {
      _curCenterAngleRad = MENU_DEST_CENTER_ANGLE_RAD;
      status = SHOW;
    }
  }
  else if (status == SHOW_TO_HIDE)
  { 
    _curCenterAngleRad -= MENU_DEST_CENTER_ANGLE_RAD / MENU_STEP;
    if (_curCenterAngleRad <= 0.0f)
    {
      _curCenterAngleRad = 0.0f;
      status = HIDE;
    }
  }
  for (size_t i = 0; i < __items.size (); ++i)
    __items[i]->doAnimation ();
}

void RoundMenu::addMenuItem (const std::wstring& itemLabel)
{
  __items.push_back (Ptr< BaseMenuItem > (
    new RoundMenuItem (itemLabel)));
  float angle = 360.0f / (float) __items.size ();
  for (size_t i = 0; i < __items.size (); ++i)
  {
    ((RoundMenuItem*)(BaseMenuItem*)__items[i])->angleDeg = angle;
  }
}

unsigned int RoundMenu::__getItemIndex (float longitude, float latitude)
{
  Vector3f centerVector = SRTransform::sphericalToRectangular (
    __globeRadius, __longitude, __latitude);

  Vector3f pointVector = SRTransform::sphericalToRectangular (
    __globeRadius, longitude, latitude);

  double angle = abs (centerVector.angle (pointVector));
  if (angle > _curCenterAngleRad || angle < INNER_RATE * _curCenterAngleRad)
    return -1;

  Vector3f centerNormal = SRTransform::sphericalToRectangular (
    __globeRadius, __longitude, __latitude + PI / 2.0f);
  Vector3f pointNormal = centerVector.cross (pointVector);
  double angleDirection = centerNormal.angle (pointNormal);
  if (latitude < __latitude)
    angleDirection = 2 * PI - angleDirection;
  double deltaAngle = 2 * PI / (double) __items.size ();
  return (unsigned int) (angleDirection / deltaAngle);
}
